import { useState, useRef, useEffect } from "react";
import {
  Upload,
  Button,
  Select,
  Card,
  Row,
  Col,
  Slider,
  Typography,
  Divider,
  message,
  Tooltip,
} from "antd";
import {
  InboxOutlined,
  DownloadOutlined,
  InfoCircleOutlined,
} from "@ant-design/icons";
import ReactCrop, { type Crop } from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import { imgToolsData } from "@/components/ToolsData";
import ToolTitle from "@/components/ToolTitle";

const { Dragger } = Upload;
const { Option } = Select;
const { Title } = Typography;

// ICO尺寸选项
const icoSizes = [16, 32, 48, 64, 128, 256];

// 创建全图裁剪
function createFullImageCrop(
  mediaWidth: number,
  mediaHeight: number,
  aspect: number
): Crop {
  // 根据图片比例和要求的裁剪比例决定初始裁剪区域
  if (mediaWidth / mediaHeight > aspect) {
    // 图片比裁剪区域更宽，裁剪高度为100%
    const cropWidth = mediaHeight * aspect;
    const cropX = (mediaWidth - cropWidth) / 2;

    return {
      unit: "%" as const,
      x: (cropX / mediaWidth) * 100,
      y: 0,
      width: (cropWidth / mediaWidth) * 100,
      height: 100,
    };
  } else {
    // 图片比裁剪区域更高或相等，裁剪宽度为100%
    const cropHeight = mediaWidth / aspect;
    const cropY = (mediaHeight - cropHeight) / 2;

    return {
      unit: "%" as const,
      x: 0,
      y: (cropY / mediaHeight) * 100,
      width: 100,
      height: (cropHeight / mediaHeight) * 100,
    };
  }
}

const ImageToIco = () => {
  const [src, setSrc] = useState<string | null>(null);
  const [crop, setCrop] = useState<Crop>();
  const [completedCrop, setCompletedCrop] = useState<Crop>();
  const [selectedSize, setSelectedSize] = useState<number>(32);
  const [scale, setScale] = useState(1);
  const [activePreview, setActivePreview] = useState<boolean>(false);
  const imgRef = useRef<HTMLImageElement>(null);
  const previewCanvasRef = useRef<HTMLCanvasElement>(null);
  const sizePreviewRef = useRef<HTMLCanvasElement | null>(null);

  // 处理文件上传
  const handleFile = (file: File) => {
    if (!file.type.startsWith("image/")) {
      message.error("请选择图片文件");
      return false;
    }

    const reader = new FileReader();
    reader.onload = (e) => {
      const dataUrl = e.target?.result as string;
      setSrc(dataUrl);

      // 预加载图片以确保尺寸和加载状态正确
      const img = new Image();
      img.onload = () => {
        // 设置裁剪区域并触发完成事件
        const aspect = 1;
        const initialCrop = createFullImageCrop(img.width, img.height, aspect);
        setCrop(initialCrop);

        // 手动创建PixelCrop以立即触发预览渲染
        const pixelCrop = {
          unit: "px" as const,
          x: (initialCrop.x * img.width) / 100,
          y: (initialCrop.y * img.height) / 100,
          width: (initialCrop.width * img.width) / 100,
          height: (initialCrop.height * img.height) / 100,
        };

        // 强制延迟一帧以确保图像已加载到DOM
        setTimeout(() => {
          setCompletedCrop(pixelCrop);
        }, 50);
      };
      img.src = dataUrl;
    };
    reader.readAsDataURL(file);
    return false;
  };

  // 图片加载完成后的处理
  const onImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
    const { width, height } = e.currentTarget;

    // 设置初始裁剪为整个图片（保持1:1比例）
    const aspect = 1; // 正方形裁剪
    const crop = createFullImageCrop(width, height, aspect);
    setCrop(crop);

    // 创建像素裁剪数据以触发预览更新
    const pixelCrop = {
      unit: "px" as const,
      x: (crop.x * width) / 100,
      y: (crop.y * height) / 100,
      width: (crop.width * width) / 100,
      height: (crop.height * height) / 100,
    };

    setCompletedCrop(pixelCrop);
  };

  // 当裁剪区域变化时，更新Canvas
  useEffect(() => {
    if (
      completedCrop?.width &&
      completedCrop?.height &&
      imgRef.current &&
      previewCanvasRef.current
    ) {
      const image = imgRef.current;
      const canvas = previewCanvasRef.current;
      const ctx = canvas.getContext("2d");
      if (!ctx) return;

      const scaleX = image.naturalWidth / image.width;
      const scaleY = image.naturalHeight / image.height;

      const pixelRatio = window.devicePixelRatio;

      canvas.width = completedCrop.width * pixelRatio;
      canvas.height = completedCrop.height * pixelRatio;

      ctx.scale(pixelRatio, pixelRatio);
      ctx.imageSmoothingQuality = "high";

      const cropX = completedCrop.x * scaleX;
      const cropY = completedCrop.y * scaleY;
      const cropWidth = completedCrop.width * scaleX;
      const cropHeight = completedCrop.height * scaleY;

      ctx.drawImage(
        image,
        cropX,
        cropY,
        cropWidth,
        cropHeight,
        0,
        0,
        completedCrop.width,
        completedCrop.height
      );

      // 更新尺寸预览
      updateSizePreview();
    }
  }, [completedCrop]);

  // 尺寸变化时更新尺寸预览
  useEffect(() => {
    if (completedCrop) {
      updateSizePreview();
    }
  }, [selectedSize]);

  // 更新尺寸预览
  const updateSizePreview = () => {
    if (!completedCrop || !previewCanvasRef.current || !sizePreviewRef.current)
      return;

    const sourceCanvas = previewCanvasRef.current;
    const canvas = sizePreviewRef.current;
    const ctx = canvas.getContext("2d");

    if (!ctx) return;

    // 清除画布
    ctx.clearRect(0, 0, selectedSize, selectedSize);

    // 确保绘制的图像平滑
    ctx.imageSmoothingEnabled = true;
    ctx.imageSmoothingQuality = "high";

    // 绘制裁剪的图像到对应尺寸
    ctx.drawImage(
      sourceCanvas,
      0,
      0,
      sourceCanvas.width,
      sourceCanvas.height,
      0,
      0,
      selectedSize,
      selectedSize
    );
  };

  // 创建ICO文件
  const createIcoFile = async () => {
    if (!completedCrop || !imgRef.current || !previewCanvasRef.current) {
      message.warning("请先选择并裁剪图片");
      return;
    }

    try {
      message.loading({ content: "正在生成ICO文件...", key: "ico-loading" });

      const canvas = previewCanvasRef.current;

      // 创建指定尺寸的canvas
      const tempCanvas = document.createElement("canvas");
      tempCanvas.width = selectedSize;
      tempCanvas.height = selectedSize;
      const tempCtx = tempCanvas.getContext("2d");

      if (tempCtx) {
        // 确保绘制的图像平滑
        tempCtx.imageSmoothingEnabled = true;
        tempCtx.imageSmoothingQuality = "high";

        tempCtx.drawImage(
          canvas,
          0,
          0,
          canvas.width,
          canvas.height,
          0,
          0,
          selectedSize,
          selectedSize
        );
      }

      // 生成PNG但使用ICO扩展名
      const imageBlob = await new Promise<Blob>((resolve) => {
        tempCanvas.toBlob(
          (blob) => {
            if (blob) resolve(blob);
            else resolve(new Blob([], { type: "image/png" }));
          },
          "image/png",
          1
        );
      });

      // 创建下载链接
      const url = window.URL.createObjectURL(imageBlob);
      const link = document.createElement("a");
      link.download = `favicon-${selectedSize}x${selectedSize}-${Date.now()}.ico`;
      link.href = url;

      message.success({
        content: `ICO文件生成成功! (${selectedSize}x${selectedSize}px)`,
        key: "ico-loading",
      });
      link.click();

      // 清理URL对象
      setTimeout(() => window.URL.revokeObjectURL(url), 100);
    } catch (error) {
      message.error({ content: "生成ICO文件失败", key: "ico-loading" });
      console.error("Error creating ICO file:", error);
    }
  };

  // 设置预览引用
  const setPreviewRef = (ref: HTMLCanvasElement | null) => {
    if (ref) {
      sizePreviewRef.current = ref;
      // 如果主预览已存在，更新尺寸预览
      if (previewCanvasRef.current && completedCrop) {
        updateSizePreview();
      }
    }
  };

  return (
    <div className="p-4">
      <Card bordered={false} className="shadow-md">
        <ToolTitle
          title={
            imgToolsData.find((item) => item.title === "图片转ico图标")
              ?.title || ""
          }
          description={
            imgToolsData.find((item) => item.title === "图片转ico图标")
              ?.description || ""
          }
        />
        <Divider />

        <Dragger
          accept="image/*"
          beforeUpload={handleFile}
          showUploadList={false}
          className="mb-6"
        >
          <p className="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p className="ant-upload-text">拖拽图片到此区域或点击选择</p>
          <p className="ant-upload-hint">
            支持格式：JPG/JPEG/PNG/GIF/WEBP/SVG/ICO
          </p>
        </Dragger>

        {src && (
          <div className="mt-6">
            <Row gutter={16}>
              <Col span={16}>
                <div className="mb-2">
                  <Title level={5}>
                    裁剪图片{" "}
                    <span className="text-sm font-normal text-gray-500">
                      （可拖动调整裁剪区域）
                    </span>
                  </Title>
                </div>
                <div
                  style={{
                    backgroundImage: `
                      linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
                      linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
                      linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
                      linear-gradient(-45deg, transparent 75%, #f0f0f0 75%)
                    `,
                    backgroundSize: "20px 20px",
                    backgroundPosition: "0 0, 0 10px, 10px -10px, -10px 0px",
                  }}
                >
                  <ReactCrop
                    crop={crop}
                    onChange={(_, percentCrop) => setCrop(percentCrop)}
                    onComplete={(c) => setCompletedCrop(c)}
                    aspect={1}
                    minWidth={50}
                  >
                    <img
                      ref={imgRef}
                      src={src}
                      alt="Source"
                      style={{ transform: `scale(${scale})` }}
                      onLoad={onImageLoad}
                    />
                  </ReactCrop>
                </div>

                {completedCrop && (
                  <div className="mt-4">
                    <Title level={5}>预览</Title>
                    <div
                      className="border p-2 mt-2 inline-block"
                      style={{
                        backgroundImage: `
                          linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
                          linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
                          linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
                          linear-gradient(-45deg, transparent 75%, #f0f0f0 75%)
                        `,
                        backgroundSize: "16px 16px",
                        backgroundPosition: "0 0, 0 8px, 8px -8px, -8px 0px",
                      }}
                    >
                      <canvas
                        ref={previewCanvasRef}
                        style={{
                          width: Math.min(completedCrop.width, 150),
                          height: Math.min(completedCrop.height, 150),
                          display: "block",
                        }}
                      />
                    </div>
                  </div>
                )}
              </Col>

              <Col span={8}>
                <div className="sticky top-4">
                  <div className="mb-6">
                    <div className="flex items-center mb-2">
                      <Title level={5} className="mb-0 mr-2">
                        选择ICO尺寸
                      </Title>
                      <Tooltip title="选择生成ICO图标的尺寸，建议网站favicon使用32x32或48x48像素">
                        <InfoCircleOutlined />
                      </Tooltip>
                    </div>

                    <Select
                      style={{ width: "100%" }}
                      value={selectedSize}
                      onChange={setSelectedSize}
                      className="mb-2"
                    >
                      {icoSizes.map((size) => (
                        <Option key={size} value={size}>
                          {size}x{size}px
                        </Option>
                      ))}
                    </Select>

                    {/* 尺寸预览区 */}
                    {completedCrop && (
                      <div
                        className="mt-3 border p-2 rounded cursor-pointer relative"
                        style={{
                          backgroundImage: `
                            linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
                            linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
                            linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
                            linear-gradient(-45deg, transparent 75%, #f0f0f0 75%)
                          `,
                          backgroundSize: "12px 12px",
                        }}
                        onMouseEnter={() => setActivePreview(true)}
                        onMouseLeave={() => setActivePreview(false)}
                      >
                        <div className="text-sm mb-1 text-gray-700">
                          {selectedSize}x{selectedSize}px 预览效果:
                        </div>
                        <canvas
                          ref={setPreviewRef}
                          width={selectedSize}
                          height={selectedSize}
                          style={{
                            width: activePreview
                              ? selectedSize
                              : Math.min(64, selectedSize * 2),
                            height: activePreview
                              ? selectedSize
                              : Math.min(64, selectedSize * 2),
                            transition: "width 0.3s, height 0.3s",
                            margin: "0 auto",
                            display: "block",
                          }}
                        />
                        {activePreview && (
                          <div className="absolute bottom-1 right-1 text-xs text-gray-500">
                            鼠标悬停可查看实际大小
                          </div>
                        )}
                      </div>
                    )}
                  </div>

                  <div className="mb-6">
                    <Title level={5} className="mb-2">
                      缩放比例
                    </Title>
                    <Slider
                      min={0.5}
                      max={2}
                      step={0.1}
                      value={scale}
                      onChange={(value: number) => setScale(value)}
                      tipFormatter={(value: number | undefined) =>
                        `${Math.round((value || 1) * 100)}%`
                      }
                      tooltip={{
                        open: true,
                        placement: "top",
                        formatter: (value) =>
                          `${Math.round((value || 1) * 100)}%`,
                      }}
                    />
                  </div>

                  <Button
                    type="primary"
                    block
                    icon={<DownloadOutlined />}
                    onClick={createIcoFile}
                    disabled={!completedCrop}
                  >
                    生成并下载ICO文件 ({selectedSize}x{selectedSize}px)
                  </Button>

                  <div className="mt-2 text-xs text-gray-500">
                    注意：浏览器环境下生成的是PNG文件，但保存为ICO扩展名，可直接用于网站favicon。
                  </div>
                </div>
              </Col>
            </Row>
          </div>
        )}
      </Card>
    </div>
  );
};

export default ImageToIco;
